﻿using System.Collections.Generic;
using System;
using System.Text;

namespace Ex03.GarageLogic
{
    /// <summary>
    /// This class is for a Van
    /// Inherits from Fuel Powered Vehicle
    /// </summary>
    public class Van : FuelPoweredVehicle
    {
        private const string k_MaxPassengersKey = "Max Passengers";
        private const string k_IsTransportHazardousMaterialKey = "Is Transport Hazardous Material (true/false)";        
        private const int k_NumberOfWheels = 6;
        private const float k_MaxAirPressureOfWheels = 28;
        private const float k_FuelTankCapacityInLitres = 100;
        private const eFuelType k_FuelType = eFuelType.Soler;
        private const int k_MinPassengers = 1;
        private static readonly Dictionary<string, string> sr_VanForm;
        
        private bool m_IsTransportHazardousMaterial;
        private int m_MaxPassengers;

        /// <summary>
        /// This is a static constructor that will initialize the Van
        /// form 
        /// </summary>
        static Van()
        {
            sr_VanForm = new Dictionary<string, string>(FuelPoweredVehicleForm);
            foreach (KeyValuePair<string, string> keyValuePair in Wheel.CreateWheelsForm(k_NumberOfWheels))
            {
                sr_VanForm.Add(keyValuePair.Key, keyValuePair.Value);
            }

            sr_VanForm.Add(k_IsTransportHazardousMaterialKey, null);
            sr_VanForm.Add(k_MaxPassengersKey, null);
        }

        /// <summary>
        /// A constructor that will pass all input to its base
        /// </summary>
        /// <param name="i_PlateNumber">plate number needed by parent </param>
        /// <param name="i_NumberOfWheels">number of wheels needed by parent</param>
        /// <param name="i_WheelMaxAirPressure">wheel max air pressure needed by parent</param>
        public Van(string i_PlateNumber)
            : base(i_PlateNumber, k_NumberOfWheels, k_MaxAirPressureOfWheels)
        {            
        }

        /// <summary>
        /// This is the main initialization function of this object
        /// This function will receive a form with all the data needed for the initialization
        /// </summary>
        /// <param name="i_CreationForm">A key value Dictionary where key is the name of the member 
        /// to initialize and value is the new value
        /// </param>
        public override void Initialize(Dictionary<string, string> i_CreationForm)
        {      
            base.Initialize(i_CreationForm);
            initailizeMaxPassengersByForm(i_CreationForm);
        }
        
        private void initailizeMaxPassengersByForm(Dictionary<string, string> i_CreationForm)
        {
            bool isGetValueSucceded;
            bool isParseSucceded;
            string maxPassengersString;
            int maxPassengersTemp;

            isGetValueSucceded = i_CreationForm.TryGetValue(k_MaxPassengersKey, out maxPassengersString);
            isParseSucceded = int.TryParse(maxPassengersString, out maxPassengersTemp);
            if (!isGetValueSucceded || !isParseSucceded)
            {
                throw new FormatException("Max Passengers is invalid");
            }

            if (maxPassengersTemp < k_MinPassengers)
            {
                throw new ArgumentException("Max Passengers is invalid (below " + k_MinPassengers + ")");
            }

            m_MaxPassengers = maxPassengersTemp;
        }

        private void initailizeIsTransportHazardousMaterialByForm(Dictionary<string, string> i_CreationForm)
        {
            bool isGetValueSucceded;
            bool isParseSucceded;
            string isTransportHazardousMaterialString;
            bool isTransportHazardousMaterialTemp;

            isGetValueSucceded = i_CreationForm.TryGetValue(k_IsTransportHazardousMaterialKey, out isTransportHazardousMaterialString);
            isParseSucceded = bool.TryParse(isTransportHazardousMaterialString, out isTransportHazardousMaterialTemp);
            if (!isGetValueSucceded || isParseSucceded)
            {
                throw new FormatException("Transport Hazardous Material is invalid");
            }

            m_IsTransportHazardousMaterial = isTransportHazardousMaterialTemp;
        }

        /// <summary>
        /// A property to get the Number Of Wheels
        /// </summary>
        public int NumberOfWheels
        {
            get { return k_NumberOfWheels; }
        }

        /// <summary>
        /// A property to get the Max Air Pressure Of Wheels
        /// </summary>
        public float MaxAirPressureOfWheels
        {
            get { return k_MaxAirPressureOfWheels; }
        }

        /// <summary>
        /// A property to get the Fuel Type
        /// </summary>
        public override eFuelType FuelType
        {
            get { return k_FuelType; }
        }

        /// <summary>
        /// A property to get the Fuel Capacity In Liters
        /// </summary>
        public override float FuelCapacityInLitres
        {
            get { return k_FuelTankCapacityInLitres; }
        }

        /// <summary>
        /// A method to get the form of the Fuel Powered Car 
        /// </summary>
        public override Dictionary<string, string> GetForm()
        {
            return new Dictionary<string, string>(sr_VanForm);
        }

        /// <summary>
        /// Return a string representation object members as pair 
        /// members name and variable value
        /// </summary>
        /// <returns>string "varName + Vehicle.k_ToStirngPairDelimiter + varValue + Vehicle.sr_ToStirngEndOfPairDelimiter"</returns>
        public override string ToString()
        {
            StringBuilder stringBuilderResult = new StringBuilder();

            stringBuilderResult.Append(base.ToString());
            stringBuilderResult.Append(maxPassengersToString());
            stringBuilderResult.Append(isTransportHazardousMaterialToString());

            return stringBuilderResult.ToString();
        }

        private string maxPassengersToString()
        {
            StringBuilder stringBuilderResult = new StringBuilder();

            stringBuilderResult.Append(k_MaxPassengersKey);
            stringBuilderResult.Append(Vehicle.k_ToStirngPairDelimiter);
            stringBuilderResult.Append(m_MaxPassengers);
            stringBuilderResult.Append(Vehicle.sr_ToStirngEndOfPairDelimiter);

            return stringBuilderResult.ToString();
        }

        private string isTransportHazardousMaterialToString()
        {
            StringBuilder stringBuilderResult = new StringBuilder();

            stringBuilderResult.Append(k_IsTransportHazardousMaterialKey);
            stringBuilderResult.Append(Vehicle.k_ToStirngPairDelimiter);
            stringBuilderResult.Append(m_IsTransportHazardousMaterial);
            stringBuilderResult.Append(Vehicle.sr_ToStirngEndOfPairDelimiter);

            return stringBuilderResult.ToString();
        }
    }
}
